package com.dongnao.network.netty_hashcat;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.DefaultFileRegion;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;

import javax.activation.MimetypesFileTypeMap;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;

import static io.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;

/**
 * 处理静态资源
 */
public class StaticFileHandler extends SimpleChannelInboundHandler<File> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, File file) throws Exception {
        RandomAccessFile raf;
        try {
            raf = new RandomAccessFile(file, "r");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            sendError(ctx, NOT_FOUND);
            return;
        }

        long fileLength = raf.length();
        //创建一个响应对象
        DefaultHttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, OK);
        //设置响应内容的长度
        HttpUtil.setContentLength(response, fileLength);
        setContentTypeHeader(response, file);

        //写入响应头信息
        ctx.write(response);
        //将文件内容写到客户端
        ctx.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength), ctx.newProgressivePromise());
    }

    //发送出错的结果
    private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
        DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, Unpooled.copiedBuffer("Failure: " + status + "\r\n", CharsetUtil.UTF_8));
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");

        sendAndCleanupConnection(ctx, response, false);
    }

    //发送响应结果
    private void sendAndCleanupConnection(ChannelHandlerContext ctx, FullHttpResponse response, boolean b) {
        HttpUtil.setContentLength(response, response.content().readableBytes());
        ctx.writeAndFlush(response);
    }

    private void setContentTypeHeader(HttpResponse response, File file) {
        MimetypesFileTypeMap mimetypesMap = new MimetypesFileTypeMap();
        if (file.getPath().endsWith(".css")) {
            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/css");
        } else {
            response.headers().set(HttpHeaderNames.CONTENT_TYPE, mimetypesMap.getContentType(file));
        }
    }
}
